home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / lib / stdio / setvbuf.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  4KB  |  204 lines

  1.  
  2. /*
  3.  *  SETVBUF
  4.  *
  5.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  6.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  7.  *    DICE-LICENSE.TXT.
  8.  *
  9.  *  SendPacket call written by Phil Lindsay, Carolyn Scheppner, and Andy
  10.  *  Finkel and is freely redistributable.
  11.  *
  12.  *  Hacked because my stdio utilizes two buffers to support full
  13.  *  duplex streams.
  14.  */
  15.  
  16. #include <clib/exec_protos.h>
  17. #include <clib/dos_protos.h>
  18. #include <clib/alib_protos.h>
  19. #include <exec/types.h>
  20. #include <exec/ports.h>
  21. #include <exec/memory.h>
  22. #include <libraries/dos.h>
  23. #include <libraries/dosextens.h>
  24.  
  25. #include <stdio.h>
  26. #include <fcntl.h>
  27. #include <stdlib.h>
  28. #include <errno.h>
  29.  
  30. typedef struct MsgPort    MsgPort;
  31.  
  32. #ifdef NOTDEF
  33. extern __stkargs MsgPort *CreatePort(char *, char *);
  34. extern __stkargs void DeletePort(MsgPort *);
  35. #endif
  36.  
  37. int set_console_raw(int, short);
  38. long SendPacket(MsgPort *, long, long *, long);
  39.  
  40.  
  41. int
  42. setvbuf(fi, buf, mode, bytes)
  43. FILE *fi;
  44. char *buf;
  45. int mode;
  46. size_t bytes;
  47. {
  48.     fflush(fi);
  49.  
  50.     switch(mode) {
  51.     case _IOFBF:
  52.     fi->sd_Flags &= ~__SIF_IOLBF;
  53.     case _IOLBF:
  54.     if (fi->sd_BufSiz == 0)         /*    was raw before    */
  55.         set_console_raw(fi->sd_Fd, 0);
  56.  
  57.     if (mode == _IOLBF)
  58.         fi->sd_Flags |= __SIF_IOLBF;
  59.     if (bytes) {
  60.         if (fi->sd_Flags & __SIF_MYBUF) {
  61.         if (fi->sd_RBuf) {
  62.             free(fi->sd_RBuf);
  63.         }
  64.  
  65.         if (fi->sd_WBuf) {
  66.             free(fi->sd_WBuf);
  67.         }
  68.         }
  69.         /*
  70.         fi->sd_Flags &= ~__SIF_MYBUF;
  71.         */
  72.         fi->sd_BufSiz = bytes;
  73.         fi->sd_WLeft = -1;
  74.         fi->sd_RLeft = -1;
  75.  
  76.         /*    What should I do?  I'm using two buffers... which one should
  77.          *    I put the user's into?  So, silently do not use the user's
  78.          *    buffer.
  79.         fi->sd_WBuf = buf;
  80.         fi->sd_WPtr = buf;
  81.         */
  82.         fi->sd_WBuf = NULL;
  83.         fi->sd_WPtr = NULL;
  84.         fi->sd_RBuf = NULL;
  85.         fi->sd_RPtr = NULL;
  86.     }
  87.     break;
  88.     case _IONBF:
  89.     if (fi->sd_BufSiz)            /*    was cooked before   */
  90.         set_console_raw(fi->sd_Fd, 1);
  91.  
  92.     fi->sd_Flags &= ~__SIF_IOLBF;
  93.     fi->sd_BufSiz = 0;
  94.     if (fi->sd_Flags & __SIF_MYBUF) {
  95.         if (fi->sd_RBuf) {
  96.         free(fi->sd_RBuf);
  97.         fi->sd_RBuf = NULL;
  98.         fi->sd_RPtr = NULL;
  99.         }
  100.         if (fi->sd_WBuf) {
  101.         free(fi->sd_WBuf);
  102.         fi->sd_WBuf = NULL;
  103.         }
  104.     }
  105.     fi->sd_Flags &= ~__SIF_MYBUF;
  106.     fi->sd_WBuf = NULL;
  107.     fi->sd_WPtr = NULL;
  108.     fi->sd_RBuf = NULL;
  109.     fi->sd_RPtr = NULL;
  110.     fi->sd_WLeft = -1;
  111.     fi->sd_RLeft = -1;
  112.  
  113.  
  114.     break;
  115.     default:
  116.     return(EOF);
  117.     }
  118.     return(0);
  119. }
  120.  
  121. int
  122. set_console_raw(fd, rawmode)
  123. int fd;
  124. short rawmode;
  125. {
  126.     MsgPort *mp;
  127.     BPTR fh;
  128.     long Arg[1], res;
  129.  
  130.     fh = (BPTR)fdtofh(fd);
  131.     if (fh == NULL)
  132.     return(-1);
  133.     if (IsInteractive(fh) == 0) {
  134.     errno = ENOTTY;
  135.     return(-1);
  136.     }
  137.     mp = ((struct FileHandle *)(BADDR(fh)))->fh_Type;
  138.     if (rawmode)
  139.     Arg[0] = -1L;
  140.     else
  141.     Arg[0] = 0L;
  142.     res = SendPacket(mp, ACTION_SCREEN_MODE, Arg, 1);    /* Put it in RAW: mode */
  143.     if (res == 0) {
  144.     errno = ENXIO;
  145.     return (-1);
  146.     }
  147.     return (0);
  148. }
  149.  
  150. /*
  151.  * Function - SendPacket written by Phil Lindsay, Carolyn Scheppner, and Andy
  152.  * Finkel. This function will send a packet of the given type to the Message
  153.  * Port supplied.
  154.  */
  155.  
  156. typedef struct StandardPacket StandardPacket;
  157.  
  158. long
  159. SendPacket(pid, action, args, nargs)
  160. MsgPort *pid;    /* process indentifier ... (handler's message port )    */
  161. long action;    /* packet type ... (what you want handler to do )    */
  162. long *args;    /* a pointer to an argument list    */
  163. long nargs;    /* number of arguments in list        */
  164. {
  165.     MsgPort *replyport;
  166.     StandardPacket *packet;
  167.     long count, *pargs, res1;
  168.  
  169.     replyport = CreatePort(NULL, 0L);
  170.     if (!replyport)
  171.     return(0);
  172.  
  173.     /* Allocate space for a packet, make it public and clear it */
  174.  
  175.     packet = AllocMem(sizeof(StandardPacket), MEMF_PUBLIC | MEMF_CLEAR);
  176.     if (!packet) {
  177.     DeletePort(replyport);
  178.     return(0);
  179.     }
  180.     packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
  181.     packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
  182.     packet->sp_Pkt.dp_Port = replyport;
  183.     packet->sp_Pkt.dp_Type = action;
  184.  
  185.     /* copy the args into the packet */
  186.  
  187.     pargs = &(packet->sp_Pkt.dp_Arg1);        /* address of first argument */
  188.     for (count = 0; count < nargs; count++)
  189.     pargs[count] = args[count];
  190.  
  191.     PutMsg(pid, &packet->sp_Msg);   /* send packet */
  192.  
  193.     WaitPort(replyport);
  194.     GetMsg(replyport);
  195.  
  196.     res1 = packet->sp_Pkt.dp_Res1;
  197.  
  198.     FreeMem(packet, sizeof(StandardPacket));
  199.     DeletePort(replyport);
  200.  
  201.     return (res1);
  202. }
  203.  
  204.